#include "Cal.h"

#include <time.h>

#include <iostream>

#include "Luly/Luly.h"
#include "Luly/UI/Button.h"
#include "Luly/UI/CheckBox.h"
#include "Luly/UI/HLayout.h"
#include "Luly/UI/Layout.h"
#include "Luly/UI/LulyUI.h"
#include "Luly/UI/Panel.h"
#include "Luly/UI/TextView.h"
#include "Luly/UI/VLayout.h"

void Cal::clickToInputButtonName(Button *&button) {
  auto func = [this, button]() {
    std::string &str = textView->getTextStr();
    if (str != "0" && str != "-0" && str != "nan" && str != "-nan" &&
        str != "inf" && str != "-inf") {
      if (str[str.size() - 1] == '%') {
        str.insert(str.size() - 1, button->getTextStr());
        textView->setText(str);

      } else {
        textView->setText(str + button->getTextStr());
      }
    } else {
      if (str == "-0") {
        textView->setText('-' + button->getTextStr());
      } else {
        textView->setText(button->getTextStr());
      }
    }
    sound[std::stoi(button->getId().erase(0, 6))]->play();
    // printf("点击%s\n", button->getTextStr().c_str());
  };
  button->setCouldCancel(false);
  button->onButtonDown(func);
}

void Cal::clickToOperate(Button *&button) {
  button->onButtonDown([this, &button]() {
    soundOP[button->getTextStr()]->play();
    // if(operate_list)
    operate_list.push_back(textView->getTextStr());
    if (button->getTextStr() == "/") {
      operate_list.push_back("÷");
      soundOP["/"]->play();
    } else {
      operate_list.push_back(button->getTextStr());
      soundOP[button->getTextStr()]->play();
    }
    textView_formula->setText(" ");
    //显示式子
    for (auto i : operate_list) {
      textView_formula->setText(textView_formula->getTextStr() + i);
    }
    //清屏
    textView->setText("0");
  });
  button->setCouldCancel(false);
}

void Cal::eventBind() {
  clickToInputButtonName(button0);
  clickToInputButtonName(button1);
  clickToInputButtonName(button2);
  clickToInputButtonName(button3);
  clickToInputButtonName(button4);
  clickToInputButtonName(button5);
  clickToInputButtonName(button6);
  clickToInputButtonName(button7);
  clickToInputButtonName(button8);
  clickToInputButtonName(button9);

  clickToOperate(buttonPlus);
  clickToOperate(buttonSub);
  clickToOperate(buttonX);
  clickToOperate(buttonDivide);

  buttonBS->onClicked([this]() {
    if (textView->getTextStr() == "nan" || textView->getTextStr() == "-nan" ||
        textView->getTextStr() == "inf" || textView->getTextStr() == "-inf") {
      textView->setText("0");
    } else if (textView->getTextStr().size() > 1) {
      std::string temp = textView->getTextStr();
      temp.erase(temp.end() - 1);
      textView->setText(temp);
    } else {
      textView->setText("0");
    }
  });

  //当按下时，开始计时
  buttonBS->onButtonHolding([this]() {
    if (isTimeKeeping == false) {
      start = std::chrono::system_clock::now();
      isTimeKeeping = true;
    } else {
      if (std::chrono::system_clock::now() - start >=
          std::chrono::milliseconds(600)) {
        //计时结束
        isTimeKeeping = false;
        //清屏
        textView->setText("0");
      }
    }
  });
  buttonBS->onButtonUp([this] {
    //抬起时强制结束计时
    isTimeKeeping = false;
  });

  buttonDot->onButtonDown([this]() {
    std::string temp = textView->getTextStr();
    soundOP["dot"]->play();
    if (temp.find('.') == temp.npos) {
      temp.push_back('.');
      textView->setText(temp);
    }
  });
  buttonDot->setCouldCancel(false);
  buttonPoM->onButtonDown([this]() {
    soundOP["+/-"]->play();
    std::string temp = textView->getTextStr();
    if (temp[0] == '-') {
      temp.erase(0, 1);
      textView->setText(temp);
    } else {
      temp.insert(temp.begin(), '-');
      textView->setText(temp);
    }
  });
  buttonPoM->setCouldCancel(false);

  //百分比按钮
  buttonPercent->onButtonDown([this]() {
    soundOP["%"]->play();
    std::string &str = textView->getTextStr();
    if (str.find('%') == str.npos) {
      str.push_back('%');
    } else {
      str.erase(str.size() - 1);
    }
    textView->setText(str);
  });
  buttonPercent->setCouldCancel(false);

  buttonEqual->onButtonDown([this]() {
    operate_list.push_back(textView->getTextStr());
    soundOP["="]->play();
    //乘除处理
    // for循环先不要++
    int index = 0;
    for (auto i = operate_list.begin(); i != operate_list.end(); index++) {
      //处理%
      if (index % 2 == 1) {
        if ((*(i - 1))[(*(i - 1)).size() - 1] == '%') {
          (*(i - 1)).erase((*(i - 1)).end() - 1);
          *(i - 1) = std::to_string(std::stod(*(i - 1)) / std::stod("100"));
        }
        if ((*(i + 1))[(*(i + 1)).size() - 1] == '%') {
          (*(i - 1)).erase((*(i - 1)).end() - 1);
          *(i + 1) = std::to_string(std::stod(*(i + 1)) / std::stod("100"));
        }
      }

      if (*i == "x") {
        *(i) = std::to_string(std::stod(*(i - 1)) * std::stod(*(i + 1)));
        i = operate_list.erase(i -
                               1);  //返回的是原来i-1的下一个迭代器,即原来的i
        //注意，如果对迭代器进行迭代时，如果有erase操作，那么erase的返回值才是下一个迭代器
        i = operate_list.erase(i + 1);  //返回的是i+1的下一个迭代器，即原来的i+2
      } else if (*i == "÷") {
        *(i) = std::to_string(std::stod(*(i - 1)) / std::stod(*(i + 1)));
        i = operate_list.erase(i - 1);
        i = operate_list.erase(i + 1);
      } else {
        i++;  //如果没有erase操作，那么才能进行+-操作
      }
    }
    //处理加减
    for (size_t i = 0; i < operate_list.size(); i++) {
      if (i % 2 == 0) {
        //处理加减
        if (i == 0) {
          if ((operate_list[i])[operate_list[i].size() - 1] == '%') {
            result = std::stod(operate_list[i]) / 100;
          } else {
            //如果没有%
            result = std::stod(operate_list[i]);
          }
        } else {
          if (operate_list[i - 1] == "+") {
            if ((operate_list[i])[operate_list[i].size() - 1] == '%') {
              result += std::stod(operate_list[i]) / 100;
            } else {
              //如果没有%
              result += std::stod(operate_list[i]);
            }
          } else {
            if ((operate_list[i])[operate_list[i].size() - 1] == '%') {
              result -= std::stod(operate_list[i]) / 100;
            } else {
              //如果没有%
              result -= std::stod(operate_list[i]);
            }
          }
        }
      }
    }
    std::string str_result = std::to_string(result);
    //去除小数点后面的0
    size_t dotPos = str_result.find('.');
    if (dotPos != str_result.npos) {
      for (size_t i = str_result.size() - 1; i > dotPos; i--) {
        if (str_result[i] == '0') {
          str_result.erase(i, 1);
          if (i == dotPos + 1) {
            str_result.erase(dotPos, 1);
          }
        } else {
          break;
        }
      }
    }

    //显示结果
    //如果还有=号，则先清空
    if (textView_formula->getTextStr().find('=') !=
        textView_formula->getTextStr().npos) {
      textView_formula->setText(" ");
    }
    textView_formula->setText(textView_formula->getTextStr() +
                              textView->getTextStr() + "=" + str_result);
    textView->setText(str_result);
    //清除操作列表
    operate_list.clear();
    result = 0;
  });
  buttonEqual->setCouldCancel(false);
}

void Cal::init() {
  //创建fps显示
  fpsView = new TextView("fps", "FPS:");

  Layout *mainLayout = new Layout("mainLayout");
  Panel *mainPanel = new Panel("mainPanel");
  mainPanel->setArrangement(Layout::Arrangement::VERTICAL);
  mainPanel->setWHMode(UIObject::WHMode::FILL, UIObject::WHMode::FILL);
  mainLayout->setWHMode(UIObject::WHMode::FILL, UIObject::WHMode::FILL);
  mainLayout->addChild(mainPanel);

  Panel *textPanel = new Panel("textPanel");
  textPanel->setAlignment(Layout::Alignment::CENTER_RIGHT);
  textPanel->setWHMode(UIObject::WHMode::FILL, UIObject::WHMode::FILL);
  textPanel->setWeight(1);

  Layout *formula_scroll_layout =
      new Layout("formula_scroll_layout", Layout::Arrangement::HORIZONTAL,
                 Layout::Alignment::CENTER_RIGHT);
  formula_scroll_layout->setWHMode(UIObject::WHMode::FILL);
  HorizontalScrollView *formula_scroll = new HorizontalScrollView(
      "formula_scroll", HorizontalScrollView::Alignment::Right);
  textView_formula = new TextView("textView_formula", " ");  //式子显示
  formula_scroll->addChild(textView_formula);
  formula_scroll_layout->addChild(formula_scroll);

  textPanel->addChild(formula_scroll_layout);

  Layout *text_scroll_layout =
      new Layout("text_scroll_layout", Layout::Arrangement::HORIZONTAL,
                 Layout::Alignment::CENTER_RIGHT);
  text_scroll_layout->setWHMode(UIObject::WHMode::FILL);
  HorizontalScrollView *text_scroll = new HorizontalScrollView(
      "text_scroll", HorizontalScrollView::Alignment::Right);
  text_scroll_layout->addChild(text_scroll);
  textView = new TextView("textView", "0");
  text_scroll->addChild(textView);

  textPanel->addChild(text_scroll_layout);

  Panel *buttonPanel = new Panel("buttonPanel");
  buttonPanel->setWHMode(UIObject::WHMode::FILL, UIObject::WHMode::FILL);
  buttonPanel->setArrangement(Layout::Arrangement::HORIZONTAL);
  Layout *col_l1 = new Layout("col_l1", Layout::Arrangement::VERTICAL);
  col_l1->setWHMode(Layout::WHMode::FILL);
  buttonPanel->addChild(col_l1);
  buttonPanel->setWeight(2);

  //以下是7，4，1，.按钮
  button7 = new Button("button7", "7");
  button7->setWHMode(UIObject::WHMode::FILL);
  col_l1->addChild(button7);

  button4 = new Button("button4", "4");
  button4->setWHMode(UIObject::WHMode::FILL);
  col_l1->addChild(button4);

  button1 = new Button("button1", "1");
  button1->setWHMode(UIObject::WHMode::FILL);
  col_l1->addChild(button1);

  buttonDot = new Button("buttonDot", ".");
  buttonDot->setWHMode(UIObject::WHMode::FILL);
  col_l1->addChild(buttonDot);

  Layout *col_l2 = new Layout("col_l2", Layout::Arrangement::VERTICAL);
  col_l2->setWHMode(Layout::WHMode::FILL);
  buttonPanel->addChild(col_l2);

  //以下是8，5，2，0按钮
  button8 = new Button("button8", "8");
  button8->setWHMode(UIObject::WHMode::FILL);
  col_l2->addChild(button8);

  button5 = new Button("button5", "5");
  button5->setWHMode(UIObject::WHMode::FILL);
  col_l2->addChild(button5);

  button2 = new Button("button2", "2");
  button2->setWHMode(UIObject::WHMode::FILL);
  col_l2->addChild(button2);

  button0 = new Button("button0", "0");
  button0->setWHMode(UIObject::WHMode::FILL);
  col_l2->addChild(button0);

  Layout *col_l3 = new Layout("col_l3", Layout::Arrangement::VERTICAL);
  col_l3->setWHMode(Layout::WHMode::FILL);
  buttonPanel->addChild(col_l3);

  //以下是9，6，3，+/-按钮
  button9 = new Button("button9", "9");
  button9->setWHMode(UIObject::WHMode::FILL);
  col_l3->addChild(button9);

  button6 = new Button("button6", "6");
  button6->setWHMode(UIObject::WHMode::FILL);
  col_l3->addChild(button6);

  button3 = new Button("button3", "3");
  button3->setWHMode(UIObject::WHMode::FILL);
  col_l3->addChild(button3);

  buttonPoM = new Button("buttonPoM", "-");
  buttonPoM->setWHMode(UIObject::WHMode::FILL);
  col_l3->addChild(buttonPoM);

  Layout *col_l4 = new Layout("col_l4", Layout::Arrangement::VERTICAL);
  col_l4->setWHMode(Layout::WHMode::FILL);
  buttonPanel->addChild(col_l4);

  //以下是%，x，+按钮
  buttonPercent = new Button("buttonPercent", "%");
  buttonPercent->setWHMode(UIObject::WHMode::FILL);
  col_l4->addChild(buttonPercent);

  buttonX = new Button("buttonX", "x");
  buttonX->setWHMode(UIObject::WHMode::FILL);
  col_l4->addChild(buttonX);

  buttonPlus = new Button("buttonPlus", "+");
  buttonPlus->setWHMode(UIObject::WHMode::FILL);
  col_l4->addChild(buttonPlus);
  buttonPlus->setWeight(2);

  Layout *col_l5 = new Layout("col_l5", Layout::Arrangement::VERTICAL);
  col_l5->setWHMode(Layout::WHMode::FILL);
  buttonPanel->addChild(col_l5);

  //以下是←，÷，-，=按钮
  buttonBS = new Button("buttonBS", "<");
  buttonBS->setWHMode(UIObject::WHMode::FILL);
  col_l5->addChild(buttonBS);

  buttonDivide = new Button("buttonDivide", "/");
  buttonDivide->setWHMode(UIObject::WHMode::FILL);
  col_l5->addChild(buttonDivide);

  buttonSub = new Button("buttonSub", "-");
  buttonSub->setWHMode(UIObject::WHMode::FILL);
  col_l5->addChild(buttonSub);

  buttonEqual = new Button("buttonEqual", "=");
  buttonEqual->setWHMode(UIObject::WHMode::FILL);
  col_l5->addChild(buttonEqual);

  mainPanel->addChild(textPanel);
  mainPanel->addChild(buttonPanel);

  soundOP.insert(std::pair<std::string, SoundEffect *>(
      "+", new SoundEffect("sound+", "resources/sound/+.mp3")));
  soundOP.insert(std::pair<std::string, SoundEffect *>(
      "-", new SoundEffect("sound-", "resources/sound/-.mp3")));
  soundOP.insert(std::pair<std::string, SoundEffect *>(
      "x", new SoundEffect("soundx", "resources/sound/x.mp3")));
  soundOP.insert(std::pair<std::string, SoundEffect *>(
      "/", new SoundEffect("sound/", "resources/sound/÷.mp3")));
  soundOP.insert(std::pair<std::string, SoundEffect *>(
      "%", new SoundEffect("sound%", "resources/sound/%.mp3")));
  soundOP.insert(std::pair<std::string, SoundEffect *>(
      "=", new SoundEffect("sound=", "resources/sound/=.mp3")));
  soundOP.insert(std::pair<std::string, SoundEffect *>(
      "+/-", new SoundEffect("sound+o-", "resources/sound/+o-.mp3")));
  soundOP.insert(std::pair<std::string, SoundEffect *>(
      "dot", new SoundEffect("sounddot", "resources/sound/dot.mp3")));

  for (int i = 0; i < 10; i++) {
    sound[i] = new SoundEffect("sound" + std::to_string(i),
                               "resources/sound/" + std::to_string(i) + ".mp3");
  }

  eventBind();

  LulyUI::addUIObject(mainLayout);
  LulyUI::addUIObject(fpsView);
}

static Cal test;
void Luly::init() {
  //设置Luly属性
  Luly::setTitle("计算器");
  Luly::setMaxFPS(60);
  Luly::setWindowWH(800, 1200);
  Luly::setScale(Luly::getWindowWidth() / 200);
  // Luly::setFullScreen(true);
  test.init();

}

void Cal::update() {
  // fps信息显示1秒钟更新一次
  if (std::chrono::system_clock::now() - start >= std::chrono::seconds(1)) {
    fpsView->setText("FPS:" + std::to_string(Luly::getFPS()));
    start = std::chrono::system_clock::now();
  }
}

void Luly::update() { test.update(); }

void Luly::draw() {}

void Luly::event() {}